%include "nodo.mac"
extern malloc
extern inicializar_nodo

global agregar_item_ordenado

%define lista [ebp + 8]
%define surfacePers [ebp + 12]
%define surfaceGen [ebp + 16]
%define x [ebp + 20]
%define y [ebp + 24]
%define ID [ebp + 28]
%define nuevo_nodo [ebp - 4]
%define size_nodo 32

section .text

;void agregar_item_ordenado(Lista* laLista, SDL_Surface* surfacePers, SDL_Surface* surfaceGen, Uint32 x, Uint32 y, Uint32 ID)

agregar_item_ordenado:
	push ebp			; creo el marco de la pila
	mov ebp, esp	
	sub esp, 4			; 4 bytes para nuevo_nodo
	push ebx			; salvo registros convencion C
	push edi		
	push esi

	
	mov eax, size_nodo		; reservo memoria para el nuevo nodo
	push eax
	call malloc
	add esp, 4
	cmp eax, 0
	jz error_mem

	mov nuevo_nodo, eax		; inicializo el nuevo nodo
	push dword ID
	push dword y
	push dword x
	push dword surfaceGen
	push dword surfacePers
	push eax
	call inicializar_nodo
	add esp, 24			; restauro la pila

veresp:
	mov esi, lista
	mov eax, [esi]			; eax = primero de la lista
ver0:
	cmp eax, 0
	je seteo_primero_lista 		; if(laLista->primero == NULL), seteo el nodo como primero
	jne ciclo

error_mem:
	mov ecx, eax
	jecxz fin	

;	else, lo agrego donde corresponda dentro de la lista
ciclo:
	mov esi, eax			; eax siempre tiene el proximo elem (null en caso de no existir el prox)
	cmp esi, 0			; hay_proximo?
	je fin
	mov ecx, nuevo_nodo		; ... ecx = nuevo_nodo (no se deberia modificar)
	mov eax, [esi + _prox]		; eax = nodo actual->prox
	mov edi, esi			; ... edi = nodo actual (no se deberia modificar)
	mov ebx, [edi + _x]		; ebx = nodo_actual->coord_x
	cmp ebx, x			
	jle siguiente_nodo		; if(nodoActual->coord_x <= x)
	mov edx, [edi + _prev]		; if(nodoActual->coord_x > x)
	cmp edx, 0
	jne lo_agrego_entre

lo_agrego_primero:
	mov dword[edi + _prev], ecx		; nodo_actual->prev = nuevo_nodo
	mov [ecx + _prox], edi			; nuevo_nodo->prox = nodo_actual
	mov ebx, lista				; ebx = lista
	mov [ebx], ecx				; lista->primero = nuevo_nodo
	jmp fin

lo_agrego_entre:
	mov ebx, [edi + _prev]			; ebx = nodo_actual->prev
	mov [ebx + _prox], ecx			; nodo_actual->prev->prox = nuevo_nodo 
	mov [edi + _prev], ecx			; nodo_actual->previo = nuevo_nodo
	mov [ecx + _prev], ebx			; nuevo_nodo->prev = nodo_actual->prev
	mov [ecx + _prox], edi			; nuevo_nodo->prox = nodo_actual
	jmp fin

siguiente_nodo:
	cmp eax, 0				; hay_proximo
	jne ciclo

lo_agrego_ultimo:
	mov [edi + _prox], ecx			; nodo->actual->proximo = nuevo_nodo
	mov [ecx + _prev], edi			; nuevo_nodo->prev = nodo->actual	
	jmp fin	

seteo_primero_lista:
	mov ecx, nuevo_nodo
	mov [esi], ecx				; esi = lista, lista->primero = nuevo_nodo

fin:
	pop esi					; desarmo el stack frame
	pop edi			
	pop ebx
	add esp, 4
	pop ebp

	ret
